package cn.meike.net.protocol
{
	import flash.utils.ByteArray;

	public class MsgHead
	{
		//2 + 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1
		public var m_shMsgVersion : int; // int16_t
		public var m_uiTimeStamp_Low : uint; // uint32_t
		public var m_uiTimeStamp_High : uint; // uint32_t
		public var m_uiMsgID : uint; // uint32_t
		public var m_uiUin : uint; // uint32_t
		public var m_iFeedback : int; // int32_t
		public var m_uiBodyLength : uint; // uint32_t
		public var m_ucSKeyLength : uint; // uint8_t
		public var m_szSessionKey : Vector.<uint>; // uint8_t
		
		static public const BASEVERSION : uint = 1;
		static public const CURRVERSION : uint = 1;
		static public const VERSION_m_shMsgVersion : uint = 1;
		static public const VERSION_m_uiTimeStamp_Low : uint = 1;
		static public const VERSION_m_uiTimeStamp_High : uint = 1;
		static public const VERSION_m_uiMsgID : uint = 1;
		static public const VERSION_m_uiUin : uint = 1;
		static public const VERSION_m_iFeedback : uint = 1;
		static public const VERSION_m_uiBodyLength : uint = 1;
		static public const VERSION_m_ucSKeyLength : uint = 1;
		static public const VERSION_m_szSessionKey : uint = 1;
		
		public function MsgHead()
		{
			m_szSessionKey = new Vector.<uint>(); //max-count: 20
		}
		
		
		public function encode(buf:ByteArray, cutVersion:uint = 0):int 
		{
			// adjust cutversion
			if (cutVersion == 0 || cutVersion > CURRVERSION) 
			{
				cutVersion = CURRVERSION;
			}
			
			const savedBufBeginPos : uint = buf.position;
			
			var ret : int = ErrorMap.NO_ERROR;
			
			// 版本号
			if (VERSION_m_shMsgVersion <= cutVersion) 
			{
				buf.writeShort(m_shMsgVersion);
			}
			
			//时间戳 低位
			if (VERSION_m_uiTimeStamp_Low <= cutVersion) {
				buf.writeUnsignedInt(m_uiTimeStamp_Low);
			}
			
			//时间戳 高位
			if (VERSION_m_uiTimeStamp_High <= cutVersion) {
				buf.writeUnsignedInt(m_uiTimeStamp_High);
			}
			
			//协议号
			if (VERSION_m_uiMsgID <= cutVersion) {
				buf.writeUnsignedInt(m_uiMsgID);
			}
			
			//用户 ID 
			if (VERSION_m_uiUin <= cutVersion) {
				buf.writeUnsignedInt(m_uiUin);
			}
			
			//Feedback
			if (VERSION_m_iFeedback <= cutVersion) {
				buf.writeInt(m_iFeedback);
			}
			
			//Body 的长度
			if (VERSION_m_uiBodyLength <= cutVersion) {
				buf.writeUnsignedInt(m_uiBodyLength);
			}
			
			//Key 的长度
			if (VERSION_m_ucSKeyLength <= cutVersion) {
				buf.writeByte(m_ucSKeyLength);
			}
			
			//将Key信息写入
			if (VERSION_m_szSessionKey <= cutVersion) {
				const m_szSessionKeyRefer : int = m_ucSKeyLength;
				if (m_szSessionKeyRefer < 0) {
					return ErrorMap.ERR_MINUS_REFER_VALUE;
				}
				if (m_szSessionKeyRefer > 20) {
					return ErrorMap.ERR_REFER_BIGGER_THAN_COUNT;
				}
				for (var m_szSessionKey_i : uint = 0; m_szSessionKey_i < m_szSessionKeyRefer; m_szSessionKey_i++) {
					if (m_szSessionKey[m_szSessionKey_i] == undefined) {
						return ErrorMap.ERR_ARRAY_ELEMENT_UNDEFIND;
					}
					buf.writeByte(m_szSessionKey[m_szSessionKey_i]);
				}
			}
			
			// set versionindicator
			// no versionindicator to set
			
			// set sizeinfo
			// no sizeinfo to set
			
			return ret;
		}

		
		public function decode(buf:ByteArray, cutVersion:uint = 0):int {
			// adjust cutversion
			if (cutVersion == 0 || cutVersion > CURRVERSION) {
				cutVersion = CURRVERSION;
			}
			
			// get sizeinfo
			// no sizeinfo to get
			
			const savedBufBeginPos : uint = buf.position;
			
			// get versionindicator
			// no versionindicator to get
			
			var ret : int = ErrorMap.NO_ERROR;
			
			// decode entries
			if (VERSION_m_shMsgVersion <= cutVersion) {
				if (buf.bytesAvailable < 2) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_shMsgVersion = buf.readShort();
			}
			
			if (VERSION_m_uiTimeStamp_Low <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_uiTimeStamp_Low = buf.readUnsignedInt();
			}
			
			if (VERSION_m_uiTimeStamp_High <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_uiTimeStamp_High = buf.readUnsignedInt();
			}
			
			if (VERSION_m_uiMsgID <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_uiMsgID = buf.readUnsignedInt();
			}
			
			if (VERSION_m_uiUin <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_uiUin = buf.readUnsignedInt();
			}
			
			if (VERSION_m_iFeedback <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_iFeedback = buf.readInt();
			}
			
			if (VERSION_m_uiBodyLength <= cutVersion) {
				if (buf.bytesAvailable < 4) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_uiBodyLength = buf.readUnsignedInt();
			}
			
			if (VERSION_m_ucSKeyLength <= cutVersion) {
				if (buf.bytesAvailable < 1) {
					return ErrorMap.ERR_PARTIAL_MSG;
				}
				m_ucSKeyLength = buf.readUnsignedByte();
			}
			
			if (VERSION_m_szSessionKey <= cutVersion) {
				const m_szSessionKeyRefer : int = m_ucSKeyLength;
				if (m_szSessionKeyRefer < 0) {
					return ErrorMap.ERR_MINUS_REFER_VALUE;
				}
				if (m_szSessionKeyRefer > 20) {
					return ErrorMap.ERR_REFER_BIGGER_THAN_COUNT;
				}
				for (var m_szSessionKey_i : uint = 0; m_szSessionKey_i < m_szSessionKeyRefer; m_szSessionKey_i++) {
					if (buf.bytesAvailable < 1) {
						return ErrorMap.ERR_PARTIAL_MSG;
					}
					m_szSessionKey[m_szSessionKey_i] = buf.readUnsignedByte();
				}
			}
			
			return ret;
		}
		
		
		
	}
}






